package com.binance.healthcenter.notification;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

import com.binance.master.utils.JsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.binance.healthcenter.model.HealthCheckResult;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Lists;

import lombok.extern.log4j.Log4j2;

@Log4j2
@Service
public class NotificationStrategyService {

    private LoadingCache<String, AtomicLong> caches = CacheBuilder.newBuilder()
            .refreshAfterWrite(2, TimeUnit.MINUTES).build(new CacheLoader<String, AtomicLong>() {
                @Override
                public AtomicLong load(String s) throws Exception {
                    log.info("NotificationStrategyService.caches:refresh key={}", s);
                    return new AtomicLong(0);
                }
            });
    private LoadingCache<String, String> muteCaches = CacheBuilder.newBuilder()
            .refreshAfterWrite(24, TimeUnit.HOURS).build(new CacheLoader<String, String>() {
                @Override
                public String load(String s) throws Exception {
                    log.info("NotificationStrategyService.muteCaches:refresh key={}", s);
                    return null;
                }
            });
    private LoadingCache<String, String> eventCaches = CacheBuilder.newBuilder()
            .refreshAfterWrite(24, TimeUnit.HOURS).build(new CacheLoader<String, String>() {
                @Override
                public String load(String s) throws Exception {
                    return null;
                }
            });

    public List<HealthCheckResult> needNotification(List<HealthCheckResult> healthCheckResultList) {
        List<HealthCheckResult> pushHealthResults = Lists.newArrayList();
        for (HealthCheckResult healthCheckResult : healthCheckResultList) {
            String key = healthCheckResult.getServiceName() + healthCheckResult.getHost();
            AtomicLong atomicLong = caches.getIfPresent(key);
            if (null == atomicLong) {
                caches.put(key, new AtomicLong(1));
            } else {
                atomicLong.addAndGet(1);
                caches.put(key, atomicLong);
                Boolean needMute = needMute(healthCheckResult);
                log.info("NotificationStrategyService.needNotification key={},count={},healthCheckResult={}", key, atomicLong.get(),healthCheckResult);
                if (atomicLong.get() > 1L && atomicLong.get() % 10 == 0 && !needMute) {
                    log.info("NotificationStrategyService.pushHealthResults key={},count={},healthCheckResult={}", key,
                            atomicLong.get(), healthCheckResult);
                    pushHealthResults.add(healthCheckResult);
                }
            }
        }
        return pushHealthResults;
    }

    /**
     * 是否需要禁止
     */
    private Boolean needMute(HealthCheckResult healthCheckResult) {
        String serviceName = healthCheckResult.getServiceName().toLowerCase();
        String muteCommand = muteCaches.getIfPresent(serviceName);
        if (StringUtils.isBlank(muteCommand)) {
            return false;
        }
        String errorMessage = JsonUtils.toJsonNotNullKey(healthCheckResult.getResultMap());
        if (StringUtils.containsIgnoreCase(errorMessage, muteCommand)) {
            return true;
        }
        return false;
    }

    /**
     * 给某个服务设置禁止信息
     * */
    public void setMuteCommandInfo(String serviceName, String commandInfo) {
        muteCaches.put(serviceName, commandInfo);
    }
    /**
     * 清除某个服务的禁止信息
     * */
    public void clearMuteCommandInfo(String serviceName, String commandInfo) {
        muteCaches.invalidate(serviceName);
    }
    /**
     * 清除所有服务禁止信息
     * */
    public void clearUpAllMuteCommandInfo() {
        muteCaches.cleanUp();
    }


}
